Skip to content

Fix ambiguous trait dispatch when ADTs share constructor names - #68

Merged
ilyakooo0 merged 1 commit into
masterfrom
push-qqxklpwswmmw
Jul 12, 2026
Merged

Fix ambiguous trait dispatch when ADTs share constructor names#68
ilyakooo0 merged 1 commit into
masterfrom
push-qqxklpwswmmw

Conversation

@ilyakooo0

Copy link
Copy Markdown
Owner

Summary

Trait dispatch keyed on runtime tag string, not static type. With two ADTs sharing a constructor name (e.g. Shape and Blob both have Circle), calling a trait method polymorphically could run the wrong impl — silent wrong output.

Fix

  • Monomorphic call sites (static type known): emit a direct call to the correct impl, no runtime dispatch needed
  • Polymorphic sites (fall back to dispatcher): add compile-time check_ambiguous_dynamic_dispatch that rejects the program if that method's impls have colliding constructor names — a compile error rather than silently running the wrong code

The guard is narrow: only fires when a polymorphic site meets impls with clashing tags. Polymorphic dispatch over distinct constructors still works. No false positives across the suite including prelude min/max/compare.

Note

Operator paths (==/</+) still dispatch on tag and have the same latent bug — flagged in AGENTS.md for a separate change.

Tests

5 new tests in regress_trait_dispatch.rs: the reported bug, multi-arg method, bare-value (map area) path, ambiguous-polymorphic rejection, and a control that the guard doesn't overfire.

Verification

cargo test -p knot-compiler
# All binaries green

Trait dispatch keyed on runtime tag string, not static type. With two
ADTs sharing a constructor name (e.g. Shape and Blob both have Circle),
calling a trait method polymorphically could run the wrong impl.

Fix: for monomorphic call sites where the static type is known, emit a
direct call to the correct impl (no runtime dispatch needed). For
polymorphic sites that fall back to the dispatcher, add a compile-time
check (check_ambiguous_dynamic_dispatch) that rejects the program if
that method's impls have colliding constructor names, pointing at the
call. This is a compile error rather than silently running the wrong
code.

The guard is narrow: only fires when a polymorphic site meets impls
with clashing tags. Polymorphic dispatch over distinct constructors
still works. No false positives across the suite including prelude
min/max/compare.

5 new tests in regress_trait_dispatch.rs. Full compiler suite green.
Note: operator paths (==/</+) still dispatch on tag and have the same
latent bug — flagged in AGENTS.md for a separate change.
@ilyakooo0 ilyakooo0 added the bug Something isn't working label Jul 12, 2026
@ilyakooo0
ilyakooo0 merged commit f26f7aa into master Jul 12, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant